package phototransfer.model.udp;

import android.util.Log;
import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.SocketException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import phototransfer.model.IPhotoUdpCallback;
import phototransfer.model.IPhotoUdpServer;
import phototransfer.model.filetransfer.DataPacket;
import phototransfer.model.filetransfer.FileReceiveBuffer;
import phototransfer.utils.CommonUtils;

public class UdpFileReceiver implements IPhotoUdpServer {
   public static final String TAG = "UdpFileReceiver";
   private final int THREAD_TIMEOUT = 10000;
   private CountDownLatch mCountDownLatch;
   private int listeningPort;
   private String lastError;
   FileReceiveBuffer fileReceiver = null;
   private IPhotoUdpCallback mCallback;
   private ExecutorService executorService = Executors.newFixedThreadPool(3);

   public boolean startServer(int port, IPhotoUdpCallback callback) {
      this.mCallback = callback;
      this.listeningPort = port;
      this.mCountDownLatch = new CountDownLatch(5);

      try {
         this.fileReceiver = new FileReceiveBuffer(this.listeningPort);
      } catch (SocketException var5) {
         Log.d("UdpFileReceiver", "[error] could not open socket. message: " + var5.getMessage());
         return false;
      }

      this.fileReceiver.start();
      this.executorService.execute(new UdpFileReceiver.WorkThread());
      BroadcastSender.getInstance().startHeartBeat();
      Log.d("UdpFileReceiver", "File receiver is running");

      try {
         this.mCountDownLatch.await();
      } catch (InterruptedException var4) {
         var4.printStackTrace();
      }

      return true;
   }

   public void stopServer() {
      BroadcastSender.getInstance().stopHeartBeat();
      if (null != this.fileReceiver) {
         this.fileReceiver.stopListening();
         this.fileReceiver.close();
      }

      if (null != this.executorService) {
         this.executorService.shutdownNow();
      }

   }

   private class WorkThread implements Runnable {
      private WorkThread() {
      }

      public void run() {
         BufferedOutputStream writer = null;
         boolean initialized = false;
         String filePath = "";
         long fileLength = 0L;
         long recvedLength = 0L;
         UdpFileReceiver.this.mCallback.onError(4096, UdpFileReceiver.this.lastError);

         while(true) {
            while(true) {
               DataPacket packet = UdpFileReceiver.this.fileReceiver.getNextPacket();
               if (!initialized) {
                  if (!packet.isInitPacket()) {
                     continue;
                  }

                  filePath = CommonUtils.getFilePath(packet.getFilename());
                  fileLength = packet.getFileLength();
                  recvedLength = 0L;

                  try {
                     writer = new BufferedOutputStream(new FileOutputStream(filePath));
                     break;
                  } catch (FileNotFoundException var12) {
                     UdpFileReceiver.this.lastError = "[error] could not create new file. message: " + var12.getMessage();
                     Log.e("UdpFileReceiver", UdpFileReceiver.this.lastError);
                  }
               } else {
                  if (packet.isInitPacket()) {
                     continue;
                  }

                  if (packet.isLastPacket()) {
                     UdpFileReceiver.this.fileReceiver.sendLastAck(10);

                     try {
                        writer.close();
                     } catch (IOException var11) {
                        UdpFileReceiver.this.lastError = "[error] file writer failed to close: " + var11.getMessage();
                        Log.e("UdpFileReceiver", UdpFileReceiver.this.lastError);
                     }

                     initialized = false;
                     UdpFileReceiver.this.fileReceiver.init();
                     Log.d("UdpFileReceiver", "[completed]");
                     UdpFileReceiver.this.mCallback.onFinishedRecvFile(0, filePath);
                     continue;
                  }

                  try {
                     writer.write(packet.getData());
                     recvedLength += (long)packet.getData().length;
                     UdpFileReceiver.this.mCallback.onProgress(filePath, fileLength, recvedLength);
                     continue;
                  } catch (IOException var13) {
                     UdpFileReceiver.this.lastError = "[error] could not write to file. message: " + var13.getMessage();
                     Log.d("UdpFileReceiver", UdpFileReceiver.this.lastError);
                  }
               }

               UdpFileReceiver.this.fileReceiver.stopListening();
               UdpFileReceiver.this.fileReceiver.close();
               UdpFileReceiver.this.mCallback.onError(4097, UdpFileReceiver.this.lastError);

               try {
                  UdpFileReceiver.this.fileReceiver.join(10000L);
               } catch (InterruptedException var10) {
                  Log.d("UdpFileReceiver", "[error] interrupted while closing threads. transfer may not have finished normally.");
               }

               UdpFileReceiver.this.mCountDownLatch.countDown();
               Log.d("UdpFileReceiver", "quit");
               return;
            }

            UdpFileReceiver.this.mCallback.onStartRecvFile(0, filePath);
            initialized = true;
         }
      }

      // $FF: synthetic method
      WorkThread(Object x1) {
         this();
      }
   }
}
